package com.ndood.gateway.app.websocket;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import org.springframework.stereotype.Component;
import org.yeauty.annotation.OnClose;
import org.yeauty.annotation.OnError;
import org.yeauty.annotation.OnEvent;
import org.yeauty.annotation.OnMessage;
import org.yeauty.annotation.OnOpen;
import org.yeauty.annotation.ServerEndpoint;
import org.yeauty.pojo.ParameterMap;
import org.yeauty.pojo.Session;

import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * websocket服务 https://blog.csdn.net/moshowgame/article/details/80275084
 * https://github.com/lyswin2002/circle
 * https://gitee.com/Yeauty/netty-websocket-spring-boot-starter
 * 坑 ： application.xml需要配置host 0.0.0.0 否则handshake 403
 */
@ServerEndpoint(prefix = "netty-websocket")
@Component
@Slf4j
public class WebSocketServer {
	
	public WebSocketServer() {
		super();
		log.info("websocketServer已啓動");
	}
    
	//静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    
    //接收order_no
    private String order_no="";
	
    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, ParameterMap parameterMap) throws IOException {
    	String order_no = parameterMap.getParameter("order_no");
        
        this.session = session;
        webSocketSet.add(this);  
        
        //加入set中
        addOnlineCount();           //在线数加1
        this.order_no = order_no;
        log.info("有新客户端开始监听:"+order_no+",当前在线人数为" + getOnlineCount());
    }

    @OnClose
    public void onClose(Session session) throws IOException {
       webSocketSet.remove(this);  //从set中删除
       subOnlineCount();           //在线数减1
       log.info("有一连接关闭！当前在线人数为" + getOnlineCount());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error(error.getMessage(),error);
    }

    @OnMessage
    public void onMessage(Session session, String message) {
    	log.info("收到来自窗口"+order_no+"的信息:"+message);
        //群发消息
        /*for (WebSocketServer item : webSocketSet) {
        	item.session.sendText(message);
        }*/
    }

    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    break;
                case WRITER_IDLE:
                    break;
                case ALL_IDLE:
                    break;
                default:
                    break;
            }
        }
    }

    /**
	 * 实现服务器主动推送
	 */
   public void sendMessage(String message) throws IOException {
   		this.session.sendText(message);
   }
   
   /**
   * 群发自定义消息
   * */
  public static void sendInfo(String message,String order_no) throws IOException {
  	log.info("推送消息到窗口"+order_no+"，推送内容:"+message);
      for (WebSocketServer item : webSocketSet) {
          try {
          	//这里可以设定只推送给这个order_no的，为null则全部推送
          	if(order_no==null) {
          		item.sendMessage(message);
          	}else if(item.order_no.equals(order_no)){
          		item.sendMessage(message);
          	}
          } catch (IOException e) {
        	  log.error(e.getMessage(),e);
          }
      }
  }

  public static synchronized int getOnlineCount() {
      return onlineCount;
  }

  public static synchronized void addOnlineCount() {
      WebSocketServer.onlineCount++;
  }

  public static synchronized void subOnlineCount() {
      WebSocketServer.onlineCount--;
  }

}
